package com.ccb.sc.common.modules.shopkeeper.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
//psl//psl import com.ccb.sc.common.bind.exception.BizException;
import com.ccb.sc.common.bind.page.PageParams;
import com.ccb.sc.common.bind.page.PageVo;
import com.ccb.sc.common.code.BizCodeFace;
import com.ccb.sc.common.code.ErrorCode;
import com.ccb.sc.common.modules.shopkeeper.entity.Shopkeeper;
import com.ccb.sc.common.modules.shopkeeper.entity.ShopkeeperPointsLog;
import com.ccb.sc.common.modules.shopkeeper.enums.ShopkeeperPointsLogType;
import com.ccb.sc.common.modules.shopkeeper.mapper.ShopkeeperPointsLogMapper;
import com.ccb.sc.common.modules.shopkeeper.vo.ShopkeeperPointsLogVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 店主阳光值记录 服务实现类
 * </p>
 *
 * @author ken
 * @since 2023-02-12
 */
@Slf4j
@Service
public class ShopkeeperPointsLogService extends ServiceImpl<ShopkeeperPointsLogMapper, ShopkeeperPointsLog> {

    private ShopkeeperService shopkeeperService;

    public PageVo<ShopkeeperPointsLogVo> searchByQueryParam(Long shopkeeperId, PageParams queryParam) {
        Page<ShopkeeperPointsLog> page = new Page<ShopkeeperPointsLog>(queryParam.getCurrent(), queryParam.getPageSize());
        Page<ShopkeeperPointsLog> pointsLogPage = this.page(page, Wrappers.<ShopkeeperPointsLog>lambdaQuery()
                .eq(ShopkeeperPointsLog::getShopkeeperId, shopkeeperId)
                .orderByDesc(ShopkeeperPointsLog::getId));
        List<ShopkeeperPointsLog> records = pointsLogPage.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return PageVo.create(queryParam.getCurrent(), queryParam.getPageSize(), 0, Lists.newArrayList());
        }
        List<ShopkeeperPointsLogVo> list = records.stream().map(item -> {
            ShopkeeperPointsLogVo vo = new ShopkeeperPointsLogVo();
            vo.setChangeType(item.getChangeType());
            vo.setCreateTime(item.getCreateTime());
            vo.setAmount(item.getAmount());
            vo.setBalance(item.getBalance());
            return vo;
        }).collect(Collectors.toList());

        return PageVo.create(queryParam.getCurrent(), queryParam.getPageSize(), page.getTotal(), list);
    }

    @Transactional(rollbackFor = Exception.class)
    public void award(Long shopkeeperId, BigDecimal points, ShopkeeperPointsLogType logType, String associate, Long associateMemberId) {
        if (points.compareTo(BigDecimal.ZERO) == 0) {
            log.error("店主[{}]奖励阳光值记录数量为0，类型[{}]，关联id[{}]", shopkeeperId, logType, associate);
            return;
        }
        Shopkeeper shopkeeper = this.shopkeeperService.getById(shopkeeperId);
        BigDecimal balance = shopkeeper.getPoints();
        BigDecimal totalPoints = shopkeeper.getTotalPoints();
        BigDecimal shopkeeperPoints = balance.add(points);
        Assert.isTrue(shopkeeperPoints.compareTo(BigDecimal.ZERO) >= 0, "阳光值不足！");
        // 大于0并且不是提现退回的才计入累计获得的阳光值
        if (points.compareTo(BigDecimal.ZERO) > 0 && !Objects.equals(ShopkeeperPointsLogType.WITHDRAW_RETURN, logType)) {
            totalPoints = totalPoints.add(points);
            shopkeeper.setTotalPoints(totalPoints);
        }
        shopkeeper.setPoints(shopkeeperPoints);
        shopkeeper.setVersion(shopkeeper.getVersion());
        boolean saveShopkeeper = this.shopkeeperService.updateById(shopkeeper);
        if (!saveShopkeeper) {
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.FAIL));
        }

        ShopkeeperPointsLog shopkeeperPointsLog = new ShopkeeperPointsLog();
        shopkeeperPointsLog.setShopkeeperId(shopkeeperId);
        shopkeeperPointsLog.setAmount(points);
        shopkeeperPointsLog.setBalance(balance);
        shopkeeperPointsLog.setChangeType(logType);
        shopkeeperPointsLog.setAssociate(associate);
        shopkeeperPointsLog.setAssociateMemberId(associateMemberId);
        boolean saveLog = this.save(shopkeeperPointsLog);
        if (!saveLog) {
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.FAIL));
        }
    }

    public boolean countByAssociate(Long shopkeeperId, String associate) {
        return this.count(Wrappers.<ShopkeeperPointsLog>lambdaQuery()
                .eq(ShopkeeperPointsLog::getShopkeeperId, shopkeeperId)
                .eq(ShopkeeperPointsLog::getAssociate, associate)) > 0;
    }

    @Autowired
    public void setShopkeeperService(ShopkeeperService shopkeeperService) {
        this.shopkeeperService = shopkeeperService;
    }
}
